#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mcce.h"
#define  ATOM_RAD 2.0
#define  TRUE     1
#define  FALSE    0

typedef struct {
  int x, y, z;
} INT_VECTOR;


int  insAtomToConf(CONF *conf, int ins);
void calc_gsize();
void alloc_3d_array(int x_size, int y_size, int z_size);
void free_3d_array(int x_size, int y_size);
int  fill_grid(PROT prot);
int  mkacc(ATOM *atom);
float get_sas_res(ATOM atom, RES res);
void get_pdb_size(PROT prot);
void extend_grid();
void set_vdw_rad(PROT prot, float probe_rad); 
void reset_atom_rad(PROT prot, float probe_rad);

INT_VECTOR gsize;
INT_VECTOR gindex;
VECTOR xyz_min, xyz_max;
float  PROBE_RAD;
float  grid_interval;
float  area_coeff;
CONF   ***grid;
int    num_pts;


/* preset level 2: i = j = 4, 482 uniformly distributed points on a sphere */
float point_preset[][3] = {
      { 1.000000000000,      0.000000000000,      0.000000000000},
      {-1.000000000000,      0.000000000000,      0.000000000000},
      { 0.000000000000,     -1.000000000000,      0.000000000000},
      { 0.000000000000,      1.000000000000,      0.000000000000},
      { 0.000000000000,      0.000000000000,      1.000000000000},
      { 0.000000000000,      0.000000000000,     -1.000000000000},
      { 0.577350258827,      0.577350258827,      0.577350258827},
      {-0.577350258827,      0.577350258827,     -0.577350258827},
      {-0.577350258827,      0.577350258827,      0.577350258827},
      { 0.577350258827,     -0.577350258827,      0.577350258827},
      { 0.577350258827,      0.577350258827,     -0.577350258827},
      {-0.577350258827,     -0.577350258827,      0.577350258827},
      { 0.577350258827,     -0.577350258827,     -0.577350258827},
      {-0.577350258827,     -0.577350258827,     -0.577350258827},
      { 0.434875965118,      0.862855732441,      0.257609844208},
      { 0.558577060699,      0.817659378052,      0.139373093843},
      { 0.450256109238,      0.794655859470,      0.407174974680},
      { 0.581115424633,      0.759357035160,      0.292714506388},
      { 0.707340836525,      0.635768771172,      0.308977365494},
      { 0.453537791967,      0.702389895916,      0.548590838909},
      { 0.587714135647,      0.679930448532,      0.438504993916},
      { 0.525731086731,      0.850650787354,      0.000000000000},
      { 0.000000000000,      0.525731086731,     -0.850650787354},
      {-0.525731086731,      0.850650787354,      0.000000000000},
      { 0.000000000000,      0.525731086731,      0.850650787354},
      { 0.850650787354,      0.000000000000,      0.525731086731},
      {-0.850650787354,      0.000000000000,      0.525731086731},
      { 0.000000000000,     -0.525731086731,      0.850650787354},
      {-0.850650787354,      0.000000000000,     -0.525731086731},
      {-0.525731086731,     -0.850650787354,      0.000000000000},
      { 0.850650787354,      0.000000000000,     -0.525731086731},
      { 0.525731086731,     -0.850650787354,      0.000000000000},
      { 0.000000000000,     -0.525731086731,     -0.850650787354},
      { 0.356822103262,      0.000000000000,     -0.934172332287},
      {-0.356822103262,      0.000000000000,      0.934172332287},
      { 0.934172332287,      0.356822103262,      0.000000000000},
      { 0.000000000000,      0.934172332287,     -0.356822103262},
      {-0.934172332287,     -0.356822103262,      0.000000000000},
      { 0.000000000000,      0.934172332287,      0.356822103262},
      { 0.934172332287,     -0.356822103262,      0.000000000000},
      { 0.356822103262,      0.000000000000,      0.934172332287},
      {-0.356822103262,      0.000000000000,     -0.934172332287},
      { 0.000000000000,     -0.934172332287,     -0.356822103262},
      { 0.000000000000,     -0.934172332287,      0.356822103262},
      {-0.934172332287,      0.356822103262,      0.000000000000},
      {-0.500000000000,     -0.309017002583,     -0.809017002583},
      { 0.500000000000,     -0.309017002583,      0.809017002583},
      { 0.500000000000,      0.309017002583,     -0.809017002583},
      {-0.500000000000,      0.309017002583,     -0.809017002583},
      {-0.500000000000,     -0.309017002583,      0.809017002583},
      { 0.809017002583,     -0.500000000000,     -0.309017002583},
      {-0.309017002583,     -0.809017002583,      0.500000000000},
      {-0.309017002583,      0.809017002583,     -0.500000000000},
      {-0.809017002583,      0.500000000000,      0.309017002583},
      { 0.809017002583,      0.500000000000,     -0.309017002583},
      {-0.809017002583,     -0.500000000000,      0.309017002583},
      { 0.809017002583,      0.500000000000,      0.309017002583},
      { 0.309017002583,      0.809017002583,     -0.500000000000},
      {-0.309017002583,     -0.809017002583,     -0.500000000000},
      { 0.309017002583,      0.809017002583,      0.500000000000},
      { 0.000000000000,      0.000000000000,     -1.000000000000},
      {-0.309017002583,      0.809017002583,      0.500000000000},
      { 0.309017002583,     -0.809017002583,     -0.500000000000},
      {-0.809017002583,      0.500000000000,     -0.309017002583},
      {-0.809017002583,     -0.500000000000,     -0.309017002583},
      { 0.809017002583,     -0.500000000000,      0.309017002583},
      { 0.500000000000,      0.309017002583,      0.809017002583},
      { 0.500000000000,     -0.309017002583,     -0.809017002583},
      {-0.500000000000,      0.309017002583,      0.809017002583},
      { 0.257609844208,      0.434875965118,     -0.862855732441},
      { 0.086137302220,      0.419203966856,     -0.903796672821},
      { 0.349845588207,      0.300165832043,     -0.887416779995},
      { 0.180907517672,      0.288400918245,     -0.940264523029},
      { 0.092760890722,      0.141278743744,     -0.985614418983},
      { 0.434100836515,      0.153799071908,     -0.887638628483},
      { 0.271010994911,      0.149209141731,     -0.950941443443},
      {-0.434875965118,      0.862855732441,     -0.257609844208},
      {-0.558577060699,      0.817659378052,     -0.139373093843},
      {-0.450256109238,      0.794655859470,     -0.407174974680},
      {-0.581115424633,      0.759357035160,     -0.292714506388},
      {-0.707340836525,      0.635768771172,     -0.308977365494},
      {-0.453537791967,      0.702389895916,     -0.548590838909},
      {-0.587714135647,      0.679930448532,     -0.438504993916},
      {-0.257609844208,      0.434875965118,      0.862855732441},
      {-0.086137302220,      0.419203966856,      0.903796672821},
      {-0.349845588207,      0.300165832043,      0.887416779995},
      {-0.180907517672,      0.288400918245,      0.940264523029},
      {-0.092760890722,      0.141278743744,      0.985614418983},
      {-0.434100836515,      0.153799071908,      0.887638628483},
      {-0.271010994911,      0.149209141731,      0.950941443443},
      { 0.692485809326,      0.703644096851,      0.159211650491},
      { 0.644714355469,      0.764423549175,      0.000000000434},
      { 0.800101697445,      0.578439414501,      0.158887088299},
      { 0.762022972107,      0.647549986839,     -0.000000000919},
      { 0.800101697445,      0.578439414501,     -0.158887088299},
      { 0.887638628483,      0.434100836515,      0.153799071908},
      { 0.858725130558,      0.512436449528,      0.000000000446},
      {-0.275664329529,      0.961253941059,     -0.000000000051},
      {-0.419203966856,      0.903796672821,     -0.086137302220},
      {-0.141278743744,      0.985614418983,     -0.092760890722},
      {-0.288400918245,      0.940264523029,     -0.180907517672},
      {-0.300165832043,      0.887416779995,     -0.349845588207},
      {-0.000000000277,      0.982691645622,     -0.185248702765},
      {-0.149209141731,      0.950941443443,     -0.271010994911},
      {-0.159211650491,      0.692485809326,      0.703644096851},
      {-0.139373093843,      0.558577060699,      0.817659378052},
      {-0.308977365494,      0.707340836525,      0.635768771172},
      {-0.292714506388,      0.581115424633,      0.759357035160},
      {-0.407174974680,      0.450256109238,      0.794655859470},
      {-0.453537791967,      0.702389895916,      0.548590838909},
      {-0.438504993916,      0.587714135647,      0.679930448532},
      { 0.703644096851,     -0.159211650491,      0.692485809326},
      { 0.817659378052,     -0.139373093843,      0.558577060699},
      { 0.635768771172,     -0.308977365494,      0.707340836525},
      { 0.759357035160,     -0.292714506388,      0.581115424633},
      { 0.794655859470,     -0.407174974680,      0.450256109238},
      { 0.548590838909,     -0.453537791967,      0.702389895916},
      { 0.679930448532,     -0.438504993916,      0.587714135647},
      {-0.961253941059,     -0.000000000051,      0.275664329529},
      {-0.903796672821,     -0.086137302220,      0.419203966856},
      {-0.985614418983,     -0.092760890722,      0.141278743744},
      {-0.940264523029,     -0.180907517672,      0.288400918245},
      {-0.887416779995,     -0.349845588207,      0.300165832043},
      {-0.982691645622,     -0.185248702765,      0.000000000277},
      {-0.950941443443,     -0.271010994911,      0.149209141731},
      { 0.692485809326,      0.703644096851,     -0.159211650491},
      { 0.558577060699,      0.817659378052,     -0.139373093843},
      { 0.707340836525,      0.635768771172,     -0.308977365494},
      { 0.581115424633,      0.759357035160,     -0.292714506388},
      { 0.450256109238,      0.794655859470,     -0.407174974680},
      { 0.702389895916,      0.548590838909,     -0.453537791967},
      { 0.587714135647,      0.679930448532,     -0.438504993916},
      { 0.159211650491,      0.692485809326,      0.703644096851},
      { 0.000000000434,      0.644714355469,      0.764423549175},
      { 0.158887088299,      0.800101697445,      0.578439414501},
      {-0.000000000919,      0.762022972107,      0.647549986839},
      {-0.158887088299,      0.800101697445,      0.578439414501},
      { 0.153799071908,      0.887638628483,      0.434100836515},
      { 0.000000000446,      0.858725130558,      0.512436449528},
      {-0.257609844208,     -0.434875965118,      0.862855732441},
      {-0.139373093843,     -0.558577060699,      0.817659378052},
      {-0.407174974680,     -0.450256109238,      0.794655859470},
      {-0.292714506388,     -0.581115424633,      0.759357035160},
      {-0.308977365494,     -0.707340836525,      0.635768771172},
      {-0.548590838909,     -0.453537791967,      0.702389895916},
      {-0.438504993916,     -0.587714135647,      0.679930448532},
      { 0.862855732441,     -0.257609844208,      0.434875965118},
      { 0.903796672821,     -0.086137302220,      0.419203966856},
      { 0.887416779995,     -0.349845588207,      0.300165832043},
      { 0.940264523029,     -0.180907517672,      0.288400918245},
      { 0.985614418983,     -0.092760890722,      0.141278743744},
      { 0.887638628483,     -0.434100836515,      0.153799071908},
      { 0.950941443443,     -0.271010994911,      0.149209141731},
      { 0.257609844208,      0.434875965118,      0.862855732441},
      { 0.139373093843,      0.558577060699,      0.817659378052},
      { 0.407174974680,      0.450256109238,      0.794655859470},
      { 0.292714506388,      0.581115424633,      0.759357035160},
      { 0.308977365494,      0.707340836525,      0.635768771172},
      { 0.548590838909,      0.453537791967,      0.702389895916},
      { 0.438504993916,      0.587714135647,      0.679930448532},
      {-0.000000000051,     -0.275664329529,      0.961253941059},
      {-0.086137302220,     -0.419203966856,      0.903796672821},
      {-0.092760890722,     -0.141278743744,      0.985614418983},
      {-0.180907517672,     -0.288400918245,      0.940264523029},
      {-0.349845588207,     -0.300165832043,      0.887416779995},
      {-0.185248702765,     -0.000000000277,      0.982691645622},
      {-0.271010994911,     -0.149209141731,      0.950941443443},
      { 0.000000000051,      0.275664329529,      0.961253941059},
      { 0.086137302220,      0.419203966856,      0.903796672821},
      { 0.092760890722,      0.141278743744,      0.985614418983},
      { 0.180907517672,      0.288400918245,      0.940264523029},
      { 0.349845588207,      0.300165832043,      0.887416779995},
      { 0.185248702765,      0.000000000277,      0.982691645622},
      { 0.271010994911,      0.149209141731,      0.950941443443},
      {-0.434875965118,      0.862855732441,      0.257609844208},
      {-0.419203966856,      0.903796672821,      0.086137302220},
      {-0.300165832043,      0.887416779995,      0.349845588207},
      {-0.288400918245,      0.940264523029,      0.180907517672},
      {-0.141278743744,      0.985614418983,      0.092760890722},
      {-0.153799071908,      0.887638628483,      0.434100836515},
      {-0.149209141731,      0.950941443443,      0.271010994911},
      {-0.703644096851,      0.159211650491,     -0.692485809326},
      {-0.764423549175,      0.000000000434,     -0.644714355469},
      {-0.578439414501,      0.158887088299,     -0.800101697445},
      {-0.647549986839,     -0.000000000919,     -0.762022972107},
      {-0.578439414501,     -0.158887088299,     -0.800101697445},
      {-0.434100836515,      0.153799071908,     -0.887638628483},
      {-0.512436449528,      0.000000000446,     -0.858725130558},
      {-0.862855732441,     -0.257609844208,      0.434875965118},
      {-0.817659378052,     -0.139373093843,      0.558577060699},
      {-0.794655859470,     -0.407174974680,      0.450256109238},
      {-0.759357035160,     -0.292714506388,      0.581115424633},
      {-0.635768771172,     -0.308977365494,      0.707340836525},
      {-0.702389895916,     -0.548590838909,      0.453537791967},
      {-0.679930448532,     -0.438504993916,      0.587714135647},
      {-0.692485809326,      0.703644096851,      0.159211650491},
      {-0.558577060699,      0.817659378052,      0.139373093843},
      {-0.707340836525,      0.635768771172,      0.308977365494},
      {-0.581115424633,      0.759357035160,      0.292714506388},
      {-0.450256109238,      0.794655859470,      0.407174974680},
      {-0.702389895916,      0.548590838909,      0.453537791967},
      {-0.587714135647,      0.679930448532,      0.438504993916},
      {-0.862855732441,      0.257609844208,     -0.434875965118},
      {-0.817659378052,      0.139373093843,     -0.558577060699},
      {-0.794655859470,      0.407174974680,     -0.450256109238},
      {-0.759357035160,      0.292714506388,     -0.581115424633},
      {-0.635768771172,      0.308977365494,     -0.707340836525},
      {-0.702389895916,      0.548590838909,     -0.453537791967},
      {-0.679930448532,      0.438504993916,     -0.587714135647},
      {-0.434875965118,     -0.862855732441,     -0.257609844208},
      {-0.419203966856,     -0.903796672821,     -0.086137302220},
      {-0.300165832043,     -0.887416779995,     -0.349845588207},
      {-0.288400918245,     -0.940264523029,     -0.180907517672},
      {-0.141278743744,     -0.985614418983,     -0.092760890722},
      {-0.153799071908,     -0.887638628483,     -0.434100836515},
      {-0.149209141731,     -0.950941443443,     -0.271010994911},
      { 0.703644096851,      0.159211650491,      0.692485809326},
      { 0.764423549175,      0.000000000434,      0.644714355469},
      { 0.578439414501,      0.158887088299,      0.800101697445},
      { 0.647549986839,     -0.000000000919,      0.762022972107},
      { 0.578439414501,     -0.158887088299,      0.800101697445},
      { 0.434100836515,      0.153799071908,      0.887638628483},
      { 0.512436449528,      0.000000000446,      0.858725130558},
      { 0.862855732441,     -0.257609844208,     -0.434875965118},
      { 0.817659378052,     -0.139373093843,     -0.558577060699},
      { 0.794655859470,     -0.407174974680,     -0.450256109238},
      { 0.759357035160,     -0.292714506388,     -0.581115424633},
      { 0.635768771172,     -0.308977365494,     -0.707340836525},
      { 0.702389895916,     -0.548590838909,     -0.453537791967},
      { 0.679930448532,     -0.438504993916,     -0.587714135647},
      { 0.434875965118,      0.862855732441,     -0.257609844208},
      { 0.419203966856,      0.903796672821,     -0.086137302220},
      { 0.300165832043,      0.887416779995,     -0.349845588207},
      { 0.288400918245,      0.940264523029,     -0.180907517672},
      { 0.141278743744,      0.985614418983,     -0.092760890722},
      { 0.153799071908,      0.887638628483,     -0.434100836515},
      { 0.149209141731,      0.950941443443,     -0.271010994911},
      { 0.862855732441,      0.257609844208,      0.434875965118},
      { 0.817659378052,      0.139373093843,      0.558577060699},
      { 0.794655859470,      0.407174974680,      0.450256109238},
      { 0.759357035160,      0.292714506388,      0.581115424633},
      { 0.635768771172,      0.308977365494,      0.707340836525},
      { 0.702389895916,      0.548590838909,      0.453537791967},
      { 0.679930448532,      0.438504993916,      0.587714135647},
      { 0.961253941059,     -0.000000000051,     -0.275664329529},
      { 0.903796672821,     -0.086137302220,     -0.419203966856},
      { 0.985614418983,     -0.092760890722,     -0.141278743744},
      { 0.940264523029,     -0.180907517672,     -0.288400918245},
      { 0.887416779995,     -0.349845588207,     -0.300165832043},
      { 0.982691645622,     -0.185248702765,     -0.000000000277},
      { 0.950941443443,     -0.271010994911,     -0.149209141731},
      {-0.000000000051,      0.275664329529,     -0.961253941059},
      {-0.086137302220,      0.419203966856,     -0.903796672821},
      {-0.092760890722,      0.141278743744,     -0.985614418983},
      {-0.180907517672,      0.288400918245,     -0.940264523029},
      {-0.349845588207,      0.300165832043,     -0.887416779995},
      {-0.185248702765,      0.000000000277,     -0.982691645622},
      {-0.271010994911,      0.149209141731,     -0.950941443443},
      { 0.434875965118,     -0.862855732441,      0.257609844208},
      { 0.419203966856,     -0.903796672821,      0.086137302220},
      { 0.300165832043,     -0.887416779995,      0.349845588207},
      { 0.288400918245,     -0.940264523029,      0.180907517672},
      { 0.141278743744,     -0.985614418983,      0.092760890722},
      { 0.153799071908,     -0.887638628483,      0.434100836515},
      { 0.149209141731,     -0.950941443443,      0.271010994911},
      {-0.862855732441,      0.257609844208,      0.434875965118},
      {-0.903796672821,      0.086137302220,      0.419203966856},
      {-0.887416779995,      0.349845588207,      0.300165832043},
      {-0.940264523029,      0.180907517672,      0.288400918245},
      {-0.985614418983,      0.092760890722,      0.141278743744},
      {-0.887638628483,      0.434100836515,      0.153799071908},
      {-0.950941443443,      0.271010994911,      0.149209141731},
      {-0.159211650491,     -0.692485809326,      0.703644096851},
      {-0.000000000434,     -0.644714355469,      0.764423549175},
      {-0.158887088299,     -0.800101697445,      0.578439414501},
      { 0.000000000919,     -0.762022972107,      0.647549986839},
      { 0.158887088299,     -0.800101697445,      0.578439414501},
      {-0.153799071908,     -0.887638628483,      0.434100836515},
      {-0.000000000446,     -0.858725130558,      0.512436449528},
      {-0.703644096851,      0.159211650491,      0.692485809326},
      {-0.817659378052,      0.139373093843,      0.558577060699},
      {-0.635768771172,      0.308977365494,      0.707340836525},
      {-0.759357035160,      0.292714506388,      0.581115424633},
      {-0.794655859470,      0.407174974680,      0.450256109238},
      {-0.548590838909,      0.453537791967,      0.702389895916},
      {-0.679930448532,      0.438504993916,      0.587714135647},
      {-0.692485809326,     -0.703644096851,     -0.159211650491},
      {-0.558577060699,     -0.817659378052,     -0.139373093843},
      {-0.707340836525,     -0.635768771172,     -0.308977365494},
      {-0.581115424633,     -0.759357035160,     -0.292714506388},
      {-0.450256109238,     -0.794655859470,     -0.407174974680},
      {-0.702389895916,     -0.548590838909,     -0.453537791967},
      {-0.587714135647,     -0.679930448532,     -0.438504993916},
      { 0.159211650491,     -0.692485809326,      0.703644096851},
      { 0.139373093843,     -0.558577060699,      0.817659378052},
      { 0.308977365494,     -0.707340836525,      0.635768771172},
      { 0.292714506388,     -0.581115424633,      0.759357035160},
      { 0.407174974680,     -0.450256109238,      0.794655859470},
      { 0.453537791967,     -0.702389895916,      0.548590838909},
      { 0.438504993916,     -0.587714135647,      0.679930448532},
      {-0.703644096851,     -0.159211650491,      0.692485809326},
      {-0.764423549175,     -0.000000000434,      0.644714355469},
      {-0.578439414501,     -0.158887088299,      0.800101697445},
      {-0.647549986839,      0.000000000919,      0.762022972107},
      {-0.578439414501,      0.158887088299,      0.800101697445},
      {-0.434100836515,     -0.153799071908,      0.887638628483},
      {-0.512436449528,     -0.000000000446,      0.858725130558},
      { 0.275664329529,     -0.961253941059,     -0.000000000051},
      { 0.419203966856,     -0.903796672821,     -0.086137302220},
      { 0.141278743744,     -0.985614418983,     -0.092760890722},
      { 0.288400918245,     -0.940264523029,     -0.180907517672},
      { 0.300165832043,     -0.887416779995,     -0.349845588207},
      { 0.000000000277,     -0.982691645622,     -0.185248702765},
      { 0.149209141731,     -0.950941443443,     -0.271010994911},
      { 0.961253941059,      0.000000000051,      0.275664329529},
      { 0.903796672821,      0.086137302220,      0.419203966856},
      { 0.985614418983,      0.092760890722,      0.141278743744},
      { 0.940264523029,      0.180907517672,      0.288400918245},
      { 0.887416779995,      0.349845588207,      0.300165832043},
      { 0.982691645622,      0.185248702765,      0.000000000277},
      { 0.950941443443,      0.271010994911,      0.149209141731},
      { 0.257609844208,     -0.434875965118,      0.862855732441},
      { 0.086137302220,     -0.419203966856,      0.903796672821},
      { 0.349845588207,     -0.300165832043,      0.887416779995},
      { 0.180907517672,     -0.288400918245,      0.940264523029},
      { 0.092760890722,     -0.141278743744,      0.985614418983},
      { 0.434100836515,     -0.153799071908,      0.887638628483},
      { 0.271010994911,     -0.149209141731,      0.950941443443},
      { 0.703644096851,     -0.159211650491,     -0.692485809326},
      { 0.764423549175,     -0.000000000434,     -0.644714355469},
      { 0.578439414501,     -0.158887088299,     -0.800101697445},
      { 0.647549986839,      0.000000000919,     -0.762022972107},
      { 0.578439414501,      0.158887088299,     -0.800101697445},
      { 0.434100836515,     -0.153799071908,     -0.887638628483},
      { 0.512436449528,     -0.000000000446,     -0.858725130558},
      {-0.692485809326,     -0.703644096851,      0.159211650491},
      {-0.644714355469,     -0.764423549175,      0.000000000434},
      {-0.800101697445,     -0.578439414501,      0.158887088299},
      {-0.762022972107,     -0.647549986839,     -0.000000000919},
      {-0.800101697445,     -0.578439414501,     -0.158887088299},
      {-0.887638628483,     -0.434100836515,      0.153799071908},
      {-0.858725130558,     -0.512436449528,      0.000000000446},
      { 0.692485809326,     -0.703644096851,      0.159211650491},
      { 0.558577060699,     -0.817659378052,      0.139373093843},
      { 0.707340836525,     -0.635768771172,      0.308977365494},
      { 0.581115424633,     -0.759357035160,      0.292714506388},
      { 0.450256109238,     -0.794655859470,      0.407174974680},
      { 0.702389895916,     -0.548590838909,      0.453537791967},
      { 0.587714135647,     -0.679930448532,      0.438504993916},
      {-0.159211650491,     -0.692485809326,     -0.703644096851},
      {-0.139373093843,     -0.558577060699,     -0.817659378052},
      {-0.308977365494,     -0.707340836525,     -0.635768771172},
      {-0.292714506388,     -0.581115424633,     -0.759357035160},
      {-0.407174974680,     -0.450256109238,     -0.794655859470},
      {-0.453537791967,     -0.702389895916,     -0.548590838909},
      {-0.438504993916,     -0.587714135647,     -0.679930448532},
      { 0.159211650491,      0.692485809326,     -0.703644096851},
      { 0.139373093843,      0.558577060699,     -0.817659378052},
      { 0.308977365494,      0.707340836525,     -0.635768771172},
      { 0.292714506388,      0.581115424633,     -0.759357035160},
      { 0.407174974680,      0.450256109238,     -0.794655859470},
      { 0.453537791967,      0.702389895916,     -0.548590838909},
      { 0.438504993916,      0.587714135647,     -0.679930448532},
      {-0.703644096851,     -0.159211650491,     -0.692485809326},
      {-0.817659378052,     -0.139373093843,     -0.558577060699},
      {-0.635768771172,     -0.308977365494,     -0.707340836525},
      {-0.759357035160,     -0.292714506388,     -0.581115424633},
      {-0.794655859470,     -0.407174974680,     -0.450256109238},
      {-0.548590838909,     -0.453537791967,     -0.702389895916},
      {-0.679930448532,     -0.438504993916,     -0.587714135647},
      {-0.692485809326,      0.703644096851,     -0.159211650491},
      {-0.644714355469,      0.764423549175,     -0.000000000434},
      {-0.800101697445,      0.578439414501,     -0.158887088299},
      {-0.762022972107,      0.647549986839,      0.000000000919},
      {-0.800101697445,      0.578439414501,      0.158887088299},
      {-0.887638628483,      0.434100836515,     -0.153799071908},
      {-0.858725130558,      0.512436449528,     -0.000000000446},
      {-0.159211650491,      0.692485809326,     -0.703644096851},
      {-0.000000000434,      0.644714355469,     -0.764423549175},
      {-0.158887088299,      0.800101697445,     -0.578439414501},
      { 0.000000000919,      0.762022972107,     -0.647549986839},
      { 0.158887088299,      0.800101697445,     -0.578439414501},
      {-0.153799071908,      0.887638628483,     -0.434100836515},
      {-0.000000000446,      0.858725130558,     -0.512436449528},
      { 0.257609844208,     -0.434875965118,     -0.862855732441},
      { 0.139373093843,     -0.558577060699,     -0.817659378052},
      { 0.407174974680,     -0.450256109238,     -0.794655859470},
      { 0.292714506388,     -0.581115424633,     -0.759357035160},
      { 0.308977365494,     -0.707340836525,     -0.635768771172},
      { 0.548590838909,     -0.453537791967,     -0.702389895916},
      { 0.438504993916,     -0.587714135647,     -0.679930448532},
      {-0.862855732441,     -0.257609844208,     -0.434875965118},
      {-0.903796672821,     -0.086137302220,     -0.419203966856},
      {-0.887416779995,     -0.349845588207,     -0.300165832043},
      {-0.940264523029,     -0.180907517672,     -0.288400918245},
      {-0.985614418983,     -0.092760890722,     -0.141278743744},
      {-0.887638628483,     -0.434100836515,     -0.153799071908},
      {-0.950941443443,     -0.271010994911,     -0.149209141731},
      {-0.257609844208,      0.434875965118,     -0.862855732441},
      {-0.139373093843,      0.558577060699,     -0.817659378052},
      {-0.407174974680,      0.450256109238,     -0.794655859470},
      {-0.292714506388,      0.581115424633,     -0.759357035160},
      {-0.308977365494,      0.707340836525,     -0.635768771172},
      {-0.548590838909,      0.453537791967,     -0.702389895916},
      {-0.438504993916,      0.587714135647,     -0.679930448532},
      { 0.862855732441,      0.257609844208,     -0.434875965118},
      { 0.903796672821,      0.086137302220,     -0.419203966856},
      { 0.887416779995,      0.349845588207,     -0.300165832043},
      { 0.940264523029,      0.180907517672,     -0.288400918245},
      { 0.985614418983,      0.092760890722,     -0.141278743744},
      { 0.887638628483,      0.434100836515,     -0.153799071908},
      { 0.950941443443,      0.271010994911,     -0.149209141731},
      { 0.159211650491,     -0.692485809326,     -0.703644096851},
      { 0.000000000434,     -0.644714355469,     -0.764423549175},
      { 0.158887088299,     -0.800101697445,     -0.578439414501},
      {-0.000000000919,     -0.762022972107,     -0.647549986839},
      {-0.158887088299,     -0.800101697445,     -0.578439414501},
      { 0.153799071908,     -0.887638628483,     -0.434100836515},
      { 0.000000000446,     -0.858725130558,     -0.512436449528},
      { 0.703644096851,      0.159211650491,     -0.692485809326},
      { 0.817659378052,      0.139373093843,     -0.558577060699},
      { 0.635768771172,      0.308977365494,     -0.707340836525},
      { 0.759357035160,      0.292714506388,     -0.581115424633},
      { 0.794655859470,      0.407174974680,     -0.450256109238},
      { 0.548590838909,      0.453537791967,     -0.702389895916},
      { 0.679930448532,      0.438504993916,     -0.587714135647},
      {-0.961253941059,      0.000000000051,     -0.275664329529},
      {-0.903796672821,      0.086137302220,     -0.419203966856},
      {-0.985614418983,      0.092760890722,     -0.141278743744},
      {-0.940264523029,      0.180907517672,     -0.288400918245},
      {-0.887416779995,      0.349845588207,     -0.300165832043},
      {-0.982691645622,      0.185248702765,     -0.000000000277},
      {-0.950941443443,      0.271010994911,     -0.149209141731},
      { 0.000000000051,     -0.275664329529,     -0.961253941059},
      { 0.086137302220,     -0.419203966856,     -0.903796672821},
      { 0.092760890722,     -0.141278743744,     -0.985614418983},
      { 0.180907517672,     -0.288400918245,     -0.940264523029},
      { 0.349845588207,     -0.300165832043,     -0.887416779995},
      { 0.185248702765,     -0.000000000277,     -0.982691645622},
      { 0.271010994911,     -0.149209141731,     -0.950941443443},
      { 0.434875965118,     -0.862855732441,     -0.257609844208},
      { 0.558577060699,     -0.817659378052,     -0.139373093843},
      { 0.450256109238,     -0.794655859470,     -0.407174974680},
      { 0.581115424633,     -0.759357035160,     -0.292714506388},
      { 0.707340836525,     -0.635768771172,     -0.308977365494},
      { 0.453537791967,     -0.702389895916,     -0.548590838909},
      { 0.587714135647,     -0.679930448532,     -0.438504993916},
      {-0.434875965118,     -0.862855732441,      0.257609844208},
      {-0.558577060699,     -0.817659378052,      0.139373093843},
      {-0.450256109238,     -0.794655859470,      0.407174974680},
      {-0.581115424633,     -0.759357035160,      0.292714506388},
      {-0.707340836525,     -0.635768771172,      0.308977365494},
      {-0.453537791967,     -0.702389895916,      0.548590838909},
      {-0.587714135647,     -0.679930448532,      0.438504993916},
      {-0.275664329529,     -0.961253941059,      0.000000000051},
      {-0.419203966856,     -0.903796672821,      0.086137302220},
      {-0.141278743744,     -0.985614418983,      0.092760890722},
      {-0.288400918245,     -0.940264523029,      0.180907517672},
      {-0.300165832043,     -0.887416779995,      0.349845588207},
      {-0.000000000277,     -0.982691645622,      0.185248702765},
      {-0.149209141731,     -0.950941443443,      0.271010994911},
      { 0.275664329529,      0.961253941059,      0.000000000051},
      { 0.419203966856,      0.903796672821,      0.086137302220},
      { 0.141278743744,      0.985614418983,      0.092760890722},
      { 0.288400918245,      0.940264523029,      0.180907517672},
      { 0.300165832043,      0.887416779995,      0.349845588207},
      { 0.000000000277,      0.982691645622,      0.185248702765},
      { 0.149209141731,      0.950941443443,      0.271010994911},
      {-0.257609844208,     -0.434875965118,     -0.862855732441},
      {-0.086137302220,     -0.419203966856,     -0.903796672821},
      {-0.349845588207,     -0.300165832043,     -0.887416779995},
      {-0.180907517672,     -0.288400918245,     -0.940264523029},
      {-0.092760890722,     -0.141278743744,     -0.985614418983},
      {-0.434100836515,     -0.153799071908,     -0.887638628483},
      {-0.271010994911,     -0.149209141731,     -0.950941443443},
      { 0.692485809326,     -0.703644096851,     -0.159211650491},
      { 0.644714355469,     -0.764423549175,     -0.000000000434},
      { 0.800101697445,     -0.578439414501,     -0.158887088299},
      { 0.762022972107,     -0.647549986839,      0.000000000919},
      { 0.800101697445,     -0.578439414501,      0.158887088299},
      { 0.887638628483,     -0.434100836515,     -0.153799071908},
      { 0.858725130558,     -0.512436449528,     -0.000000000446}
};


int surfw_l2(PROT prot, float probe_rad)
{
  int i, j, k;
  float res_sas;                /* sas per residue (disregard all other residues) */
  float atom_sas;               /* sas per atom */

  PROBE_RAD  = probe_rad;       /* get parameters */
  grid_interval = PROBE_RAD + ATOM_RAD;
  num_pts = 482;
  area_coeff = 4 * 3.1415926 / (float)num_pts;

  get_pdb_size(prot);

  extend_grid();

  calc_gsize();

  gindex.x = gsize.x - 1;
  gindex.y = gsize.y - 1;
  gindex.z = gsize.z - 1;

  set_vdw_rad(prot, PROBE_RAD);

  alloc_3d_array(gsize.x, gsize.y, gsize.z); 
  /* end drawing the grid */

  fill_grid(prot);

  /* make the surface for each atom */
  for (i = 0 ; i < prot.n_res; i++) {
    prot.res[i].sas = 0;
    for (j = 0; j < prot.res[i].n_conf; j++) {
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) {
        if (!(prot.res[i].conf[j].atom[k].on)) continue;
	mkacc(&(prot.res[i].conf[j].atom[k])); 
	prot.res[i].sas += prot.res[i].conf[j].atom[k].sas;
      }
    } 
  }

  /* compute the % of solvent-accessible surface of each residue */
  for (i = 0 ; i < prot.n_res; i++) {
    res_sas = 0;
    for (j = 0; j < prot.res[i].n_conf; j++) {
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) {
        if (!(prot.res[i].conf[j].atom[k].on)) continue;
	atom_sas = get_sas_res(prot.res[i].conf[j].atom[k], prot.res[i]); 
        res_sas += atom_sas;
      }
    } 
    prot.res[i].sas /= res_sas; 
  }
 
  reset_atom_rad(prot, PROBE_RAD); 

  /* print the surface area per atom */
  /*
  for (i = 0; i < prot.n_res; i++) {
    for (j = 0; j < prot.res[i].n_conf; j++) {
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) {
        if (prot.res[i].conf[j].atom[k].on) {
   	    printf("%4s  %4s %c %3d%8.3f\n", 
            prot.res[i].conf[j].atom[k].name, prot.res[i].conf[j].atom[k].resName, 
            prot.res[i].conf[j].atom[k].chainID, prot.res[i].conf[j].atom[k].resSeq,
            prot.res[i].conf[j].atom[k].sas);
	}
      }
    } 
  }
  */

  /* print the surface area per residue */
  /*
  for (i = 0; i < prot.n_res; i++) {
    printf("%4s %c %4d %8.3f\n", prot.res[i].resName, prot.res[i].chainID, prot.res[i].resSeq, 
            prot.res[i].sas);
  }
  */

  free_3d_array(gsize.x, gsize.y);

  return 0;

}


/* calculate number of grids in the x, y, z axis */
void calc_gsize()
{
  gsize.x = (int)((xyz_max.x - xyz_min.x) / grid_interval + 1);
  gsize.y = (int)((xyz_max.y - xyz_min.y) / grid_interval + 1);
  gsize.z = (int)((xyz_max.z - xyz_min.z) / grid_interval + 1);

  return;
} 


/* malloc a 3-D array of size x_size * y_size * z_size, and set array[i][j][k] to 0 */
void alloc_3d_array (int x_size, int y_size, int z_size)
{
  int i, j, k;

  grid = (CONF ***)malloc(x_size * sizeof(CONF **)); /* cast "void *" to "CONF ***" */

  for (i = 0; i < x_size; i++) 
    grid[i] = (CONF **) malloc( y_size * sizeof(CONF *) ); 

  for (i = 0; i < x_size; i++) {
    for (j = 0; j < y_size; j++) 
      grid[i][j] = (CONF *) malloc(z_size * sizeof(CONF)); 
  }
  
  for (i = 0; i < x_size; i++) 
    for (j = 0; j < y_size; j++)
      for (k = 0; k < z_size; k++) {
	grid[i][j][k].n_atom = 0;
        grid[i][j][k].atom = NULL;
      }

  return;
}



int fill_grid(PROT prot)
{
  int ix, iy, iz;                  /* x, y, z grid index for an atom */
  int i, j, k;
  int iConf;
  int ins_pos;

  /* put each atom into approriate grid box */
  for (i = 0; i < prot.n_res; i++) {
    iConf = 0;
    for (j = 0; j < prot.res[i].n_conf; j++) {
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) {

        ix = (int) ((prot.res[i].conf[j].atom[k].xyz.x - xyz_min.x) / grid_interval); 
        iy = (int) ((prot.res[i].conf[j].atom[k].xyz.y - xyz_min.y) / grid_interval); 
        iz = (int) ((prot.res[i].conf[j].atom[k].xyz.z - xyz_min.z) / grid_interval); 

        ins_pos = insAtomToConf(&(grid[ix][iy][iz]), grid[ix][iy][iz].n_atom);
        grid[ix][iy][iz].atom[ins_pos] = prot.res[i].conf[j].atom[k];  
      }
      iConf++;
    }
  }

  return 0;
} 



int mkacc(ATOM *atom)
{
  VECTOR point;
  int i, j, k, l, m;
  float d_square;
  int count;
  int ix, iy, iz;
  int ax, ay, az;         /* the grid index of this atom */
  int status;

  count = num_pts; 

  ax = (int) ((atom -> xyz.x - xyz_min.x) / grid_interval);
  ay = (int) ((atom -> xyz.y - xyz_min.y) / grid_interval);
  az = (int) ((atom -> xyz.z - xyz_min.z) / grid_interval);

  /* loop over each point */

  for (m = 0; m < num_pts; m++) {
    status = TRUE;

    point.x = point_preset[m][0] * atom -> rad + atom -> xyz.x;
    point.y = point_preset[m][1] * atom -> rad + atom -> xyz.y;
    point.z = point_preset[m][2] * atom -> rad + atom -> xyz.z;

    /* find out which grid this point belongs to */
    ix = (int) ((point.x - xyz_min.x) / grid_interval);
    iy = (int) ((point.y - xyz_min.y) / grid_interval);
    iz = (int) ((point.z - xyz_min.z) / grid_interval);

    if (grid[ix][iy][iz].n_atom >= 1) {
      for (l = 0; l < grid[ix][iy][iz].n_atom; l++) {
        if (grid[ix][iy][iz].atom[l].on &&
            status == TRUE && 
            (ix != ax || iy != ay || iz != az ||
             memcmp(atom, &(grid[ix][iy][iz].atom[l]), sizeof(ATOM)))) {
            d_square = ddvv(point, grid[ix][iy][iz].atom[l].xyz);
            if (d_square < grid[ix][iy][iz].atom[l].rad * grid[ix][iy][iz].atom[l].rad) {
              status = FALSE;
              count --;
	    }
          
        }
      }
    }

    for (i = ix - 1; i <= ix + 1; i++) {
      if (status == FALSE) break;
      for (j = iy - 1; j <= iy + 1; j++) {
        if (status == FALSE) break;
        for (k = iz - 1; k <= iz + 1; k++) {
          if (status == FALSE) break;
          for (l = 0; l < grid[i][j][k].n_atom; l++) {
            if (grid[i][j][k].atom[l].on && status == TRUE) {
               if (i != ax || j != ay || k != az ||
                   memcmp(atom, &(grid[i][j][k].atom[l]), sizeof(ATOM))) {
                  d_square = ddvv(point, grid[i][j][k].atom[l].xyz);
                  if (d_square < grid[i][j][k].atom[l].rad * grid[i][j][k].atom[l].rad) {
                      status = FALSE;
                      count --;
	           }
               }      
            }
          }
        }      
      }
    }
  }

  atom->sas = area_coeff * atom->rad * atom->rad * (float) count;

  return 0;
}


void get_pdb_size(PROT prot)
{
  int i, j, k;

  xyz_min.x = xyz_max.x = prot.res[0].conf[0].atom[0].xyz.x; 
  xyz_min.y = xyz_max.y = prot.res[0].conf[0].atom[0].xyz.y;
  xyz_min.z = xyz_max.z = prot.res[0].conf[0].atom[0].xyz.z;

  for (i = 0; i < prot.n_res; i++) {
    for (j = 0; j < prot.res[i].n_conf; j++) {
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) {

        if      (xyz_min.x > prot.res[i].conf[j].atom[k].xyz.x) 
                 xyz_min.x = prot.res[i].conf[j].atom[k].xyz.x;
        else if (xyz_max.x < prot.res[i].conf[j].atom[k].xyz.x) 
                 xyz_max.x = prot.res[i].conf[j].atom[k].xyz.x;

        if      (xyz_min.y > prot.res[i].conf[j].atom[k].xyz.y) 
                 xyz_min.y = prot.res[i].conf[j].atom[k].xyz.y;
        else if (xyz_max.y < prot.res[i].conf[j].atom[k].xyz.y) 
                 xyz_max.y = prot.res[i].conf[j].atom[k].xyz.y;

        if      (xyz_min.z > prot.res[i].conf[j].atom[k].xyz.z) 
                 xyz_min.z = prot.res[i].conf[j].atom[k].xyz.z;
        else if (xyz_max.z < prot.res[i].conf[j].atom[k].xyz.z) 
                 xyz_max.z = prot.res[i].conf[j].atom[k].xyz.z;
      }
    } 
  }

  return;
}


void extend_grid()
{
  xyz_min.x -= 2 * grid_interval;
  xyz_min.y -= 2 * grid_interval;
  xyz_min.z -= 2 * grid_interval;
  xyz_max.x += 2 * grid_interval;
  xyz_max.y += 2 * grid_interval;
  xyz_max.z += 2 * grid_interval;

  return;
}


void set_vdw_rad(PROT prot, float probe_rad)
{

  int i, j, k;

  for (i = 0; i < prot.n_res; i++) 
    for (j = 0; j < prot.res[i].n_conf; j++) 
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) 
        prot.res[i].conf[j].atom[k].rad += probe_rad;

  return;
} 


void reset_atom_rad(PROT prot, float probe_rad)
{

  int i, j, k;

  for (i = 0; i < prot.n_res; i++) 
    for (j = 0; j < prot.res[i].n_conf; j++) 
      for (k = 0; k < prot.res[i].conf[j].n_atom; k++) 
        prot.res[i].conf[j].atom[k].rad -= probe_rad;

  return;
} 


void free_3d_array(int x_size, int y_size)
{
  int i, j;

  for (i = 0; i < x_size; i++) 
    for (j = 0; j < y_size; j++) 
      free(grid[i][j]);

  for (i = 0; i < x_size; i++) 
    free(grid[i]);

  free(grid); 

  return;
}


float get_sas_res(ATOM atom, RES res)
{
  int j, k, m;
  int count;
  int status;
  VECTOR point;
  float distance;
  float surface_area;

  count = num_pts;

  for (m = 0; m < num_pts; m++) {
    status = TRUE;
    point.x = point_preset[m][0] * atom.rad + atom.xyz.x;
    point.y = point_preset[m][1] * atom.rad + atom.xyz.y;
    point.z = point_preset[m][2] * atom.rad + atom.xyz.z;

    for (j = 0; j < res.n_conf; j++) {
      if (status == FALSE) break;
      for (k = 0; k < res.conf[j].n_atom; k++) {
        if (res.conf[j].atom[k].on &&
            status == TRUE && 
            memcmp(&atom, &(res.conf[j].atom[k]), sizeof(ATOM))) {
              distance = ddvv(point, res.conf[j].atom[k].xyz);
              if (distance < res.conf[j].atom[k].rad * res.conf[j].atom[k].rad) {
                count--; status = FALSE;
              }
        }
      }
    }
  }

  surface_area = area_coeff * atom.rad * atom.rad * (float)count;
  return surface_area;
}



int insAtomToConf(CONF *conf, int ins)
{ if (ins > conf->n_atom) {
    printf("insAtomToConf(): off range insertion.\n");
    return USERERR;
  }

  /* resize the memory */
  if (!(conf->atom = (ATOM *) realloc(conf->atom, (conf->n_atom + 1) * sizeof(ATOM)))) {
    printf("insAtomToConf(): Fails resizing memory.\n");
    return USERERR;
  }
  conf->n_atom ++;

  /* move contents after position "ins" forward by 1 */
  memmove(conf->atom+ins+1, conf->atom+ins, (conf->n_atom - ins - 1) * sizeof(ATOM));

  /* reset the new slot */
  memset(conf->atom+ins, 0, sizeof(ATOM));

  return ins;
}
